<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>

<script>
    function Cat(name, color) {
        // {}

        // 原型属性 -> 所有的实例化对象都有一个原型属性([[Prototype]],__proto__) ->指向构造函数的原型对象(浅复制) -> 所有的实例化对象都可以通过原型属性访问构造函数的原型对象
        // {}[[Prototype]] = Fn.prototype;


        // this -> {}

        // 我们可以做的操作 把需要的属性和方法绑定到实例化对象上
        this.name = name;
        this.color = color;
        // return this;
    }

    // prototype(原型对象) => 存实例化对象公共的属性和方法(构造函数的原型对象)
    // Fn.prototype = {constructor:Fn}
    Cat.prototype.species = "Cat";
    Cat.prototype.call = function () {
        console.log("喵喵");
    }
    Cat.prototype.skill = function () {
        console.log("捉老鼠");
    }

    Cat.prototype.say = function () {
        // this->指向调用此方法的实例化对象 (哪个实例化对象调用它 他就指向谁)
        // console.log("say方法被调用:", this);
        console.log(this.name, this.color);
    }

    // 构造函数Object原型对象上的属性
    Object.prototype.a = 1;
    Object.prototype.b = 2;


    // 原型链(实例化对象的属性和方法查找时,基于原型[[Prototype]]链式查找机制) 
    // Tom -> Cat.prototype -> Object.prototype -> null

    var Tom = new Cat("Tom", "black");
    console.log(Tom);


    // 注意: 所有的实例化对象 都可以访问构造函数Object.prototype上的属性和方法
    // Object原型对象上的方法:
    // toString()  将实例化对象转字符串
    // valueOf()   返回实例化对象的值
    // isPrototypeOf()
    // hasOwnProperty()
    // propertyIsEnumerable()


    //  toString()  将实例化对象转字符串

    // console.log(Tom.toString()); // Object.prototype.toString "[object Object]"

    // var arr = [1, 2, 3];
    // console.log(arr);
    // console.log(arr.toString());  // Array.prototype.toString()

    // var num = new Number(1);
    // console.dir(num)
    // console.log(num.toString());  // Number.prototype.toString()


    // 强制访问 Object.prototype.toString 
    console.log(Object.prototype.toString.call(Tom));  //  "[object Object]"

    var arr = [1, 2, 3];
    console.log(Object.prototype.toString.call(arr));  //  "[object Array]"

    console.log(Object.prototype.toString.call(1));  //  "[object Number]"


    // 判断一个数据是否是纯对象数据  {a:1}

    var obj = { a: 1, b: 2 };
    var Tom = new Cat("Tom", "black");

    console.log(Object.prototype.toString.call(obj) === "[object Object]");
    console.log(Object.prototype.toString.call(Tom) === "[object Object]");


    // 判断一个数据是否是数组  {a:1}
    // var arr = [1, 2, 3];
    // console.log(Object.prototype.toString.call(Tom) === "[object Array]");
    // console.log(Object.prototype.toString.call(arr) === "[object Array]");



</script>

</html>